package com.zengraoli.PointSystem.service;

import com.zengraoli.PointSystem.model.bo.PointSystemBalancesInputBO;
import com.zengraoli.PointSystem.model.bo.PointSystemConsumePointsInputBO;
import com.zengraoli.PointSystem.model.bo.PointSystemGetBalanceInputBO;
import com.zengraoli.PointSystem.model.bo.PointSystemIssuePointsInputBO;
import com.zengraoli.PointSystem.model.bo.PointSystemSetAdminInputBO;
import com.zengraoli.PointSystem.model.bo.PointSystemTransferPointsInputBO;
import java.lang.Exception;
import java.lang.String;
import java.util.Arrays;
import javax.annotation.PostConstruct;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.transaction.manager.AssembleTransactionProcessor;
import org.fisco.bcos.sdk.transaction.manager.TransactionProcessorFactory;
import org.fisco.bcos.sdk.transaction.model.dto.CallResponse;
import org.fisco.bcos.sdk.transaction.model.dto.TransactionResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
@NoArgsConstructor
@Data
public class PointSystemService {
  public static final String ABI = com.zengraoli.PointSystem.utils.IOUtil.readResourceAsString("abi/PointSystem.abi");

  public static final String BINARY = com.zengraoli.PointSystem.utils.IOUtil.readResourceAsString("bin/ecc/PointSystem.bin");

  public static final String SM_BINARY = com.zengraoli.PointSystem.utils.IOUtil.readResourceAsString("bin/sm/PointSystem.bin");

  @Value("${system.contract.pointSystemAddress}")
  private String address;

  @Autowired
  private Client client;

  AssembleTransactionProcessor txProcessor;

  @PostConstruct
  public void init() throws Exception {
    this.txProcessor = TransactionProcessorFactory.createAssembleTransactionProcessor(this.client, this.client.getCryptoSuite().getCryptoKeyPair());
  }

  public CallResponse getBalance(PointSystemGetBalanceInputBO input) throws Exception {
    return this.txProcessor.sendCall(this.client.getCryptoSuite().getCryptoKeyPair().getAddress(), this.address, ABI, "getBalance", input.toArgs());
  }

  public TransactionResponse transferPoints(PointSystemTransferPointsInputBO input) throws Exception {
    return this.txProcessor.sendTransactionAndGetResponse(this.address, ABI, "transferPoints", input.toArgs());
  }

  public TransactionResponse issuePoints(PointSystemIssuePointsInputBO input) throws Exception {
    return this.txProcessor.sendTransactionAndGetResponse(this.address, ABI, "issuePoints", input.toArgs());
  }

  public TransactionResponse consumePoints(PointSystemConsumePointsInputBO input) throws Exception {
    return this.txProcessor.sendTransactionAndGetResponse(this.address, ABI, "consumePoints", input.toArgs());
  }

  public CallResponse admin() throws Exception {
    return this.txProcessor.sendCall(this.client.getCryptoSuite().getCryptoKeyPair().getAddress(), this.address, ABI, "admin", Arrays.asList());
  }

  public CallResponse balances(PointSystemBalancesInputBO input) throws Exception {
    return this.txProcessor.sendCall(this.client.getCryptoSuite().getCryptoKeyPair().getAddress(), this.address, ABI, "balances", input.toArgs());
  }

  public TransactionResponse setAdmin(PointSystemSetAdminInputBO input) throws Exception {
    return this.txProcessor.sendTransactionAndGetResponse(this.address, ABI, "setAdmin", input.toArgs());
  }
}
